
import React from 'react';
import Tooltip from './tooltip'
import { dateTransform } from './utils_date';

let keyIdx = 0;
/**
 * @method tw_mouth 口温点
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function tw_mouth(point, title) {
    return drawCycle(point, title, 'blue', 'blue')
}

/**
 * @method tw_anal 肛温
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function tw_anal(point, title) {
    return drawCycle(point, title, 'blue', '#fff')
}


/**
 * @method tw_axillary 腋温
 * @param {*obj} point 圆心坐标
 * @param {*string} title tooltip sting 提示语
 */
function tw_axillary(point, title) {
    keyIdx++;
    let x = point.x;
    let y = point.y;
    return (
        <Tooltip key={'tw_axillary' + keyIdx} poi_x={point.x} poi_y={point.y - 10} tooltiptext={title}>
            <g>
                <line cx={x} cy={y} x1={x - 4} y1={y - 4} x2={x + 4}
                    y2={y + 4} style={{ strokeWidth: 2, stroke: "blue" }} />
                <line x1={x + 4} y1={y - 4} x2={x - 4} y2={y + 4}
                    style={{ strokeWidth: 2, stroke: "blue" }} />
            </g>
        </Tooltip>
    );
}

/**
 * @method tw_ear 耳温
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function tw_ear(point, title) {
    keyIdx++;
    let r = 4;
    let { x, y } = point;

    let point_3 = { x: x + r, y: y + r };
    let point_2 = { x: x, y: y - r };
    let point_1 = { x: x - r, y: y + r };

    let pointSty = `${point_1.x},${point_1.y} ${point_2.x},${point_2.y} ${point_3.x},${point_3.y}`
    return (
        <Tooltip key={'tw_ear' + keyIdx} poi_x={point.x} poi_y={point.y - 10} tooltiptext={title}>
            <polygon points={pointSty} fill='#fff' stroke='blue' strokeWidth={1} />
        </Tooltip>
    )
}



/**
 * @method tw_forehead 额温
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function tw_forehead(point, title) {
    let r = 4;
    let { x, y } = point;

    let point_1 = { x: x - 0.5 * r, y: y + r };
    let poiont_11 = { x: x, y: y + 0.3 * r };

    let point_2 = { x: x + 0.5 * r, y: y + r };
    let poiont_21 = { x: x + 0.3 * r, y: y };

    let point_3 = { x: x + r, y: y - 0.4 * r };
    let poiont_31 = { x: x + 0.2 * r, y: y - 0.3 * r };

    let point_4 = { x: x, y: y - r };
    let poiont_41 = { x: x - 0.2 * r, y: y - 0.3 * r };

    let point_5 = { x: x - r, y: y - 0.4 * r };
    let poiont_51 = { x: x - 0.3 * r, y: y + 0.2 * r };

    let pointArr = [point_1, poiont_11, point_2, poiont_21, point_3, poiont_31, point_4, poiont_41, point_5, poiont_51,];
    let pointSty = ''

    pointArr.forEach(element => {
        pointSty = pointSty + `${element.x},${element.y} `;

    });
    keyIdx++;

    return (
        <Tooltip key={'tw_forehead' + keyIdx} poi_x={point.x} poi_y={point.y - 10} tooltiptext={title}>
            <polygon points={pointSty} fill='blue' stroke='blue' strokeWidth={1} />
        </Tooltip>
    )
}

/**
 * @method mb_cycle 脉搏点
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function mb_cycle(point, title) {
    return drawCycle(point, title, '#f00', '#f00')
}

/**
 * @method xl_cycle 心率圆点
 * @param {obj} point 圆心坐标
 * @param {string} title tooltip sting 提示语
 */
function xl_cycle(point, title) {
    return drawCycle(point, title, '#f00', '#fff')
}




function drawCycle(point, title, strokeColor, fillColor) {
    keyIdx++;
    return (
        <Tooltip key={'cycle' + keyIdx} poi_x={point.x} poi_y={point.y - 10} tooltiptext={title}>
            <circle strokeWidth={1} stroke={strokeColor} cx={point.x} cy={point.y} r={4} fill={fillColor} />
        </Tooltip>
    )
}

function parseRePoint(pointData, curDate) {

    let pointArray = [];
    let height = 15;
    let xl = pointData.xl || [];
    let mb = pointData.mb || [];
    let wd = pointData.wd || [];

    let events = pointData.eventDatas || []; //事件

    let xlYSection = [600, 75]; //y轴的坐标区间
    let mbYSection = [600, 75]; //y轴的坐标区间
    let wdYSection = [600, 75]; //y轴的坐标区间

    let leaveEvents = []; // 请假事件
    for (let i = 0; i < events.length; i++) {
        let value = events[i].value;
        let dataTime = events[i].dataTime;
        // 据测、外出、请假
        if (value === "请假" || value === '拒测' || value === '外出') {
            leaveEvents.push(dataTime);
        }
    }

    let xlGroup = splitGroup(leaveEvents, xl);
    let mbGroup = splitGroup(leaveEvents, mb);

    // 如果体温 把低于50度的当成请假事件，以便隔开低于50度的体温
    for (let i = 0; i < wd.length; i++) {
        if (wd[i].value < 35) {
            leaveEvents.push(wd[i].dataTime);
        }
    }
    leaveEvents.sort()
    let wdGroup = splitGroup(leaveEvents, wd, true);

    let xlPoints = [];//心率坐标
    let mbPoints = [];//脉搏坐标
    let wdPoints = [];//体温坐标


    // 心率坐标
    for (let i = 0; i < xlGroup.length; i++) {
        let xlArr = xlGroup[i];
        xlPoints[i] = [];

        for (let j = 0; j < xlArr.length; j++) {
            let xy = getXY(xlArr[j], curDate, 40, 180, xlYSection);
            xlPoints[i].push(xy);

        }
    }

    // 脉搏坐标
    for (let i = 0; i < mbGroup.length; i++) {
        let mbArr = mbGroup[i];
        mbPoints[i] = [];

        for (let j = 0; j < mbArr.length; j++) {
            let xy = getXY(mbArr[j], curDate, 40, 180, mbYSection);
            mbPoints[i].push(xy);
        }
    }



    // 温度坐标
    for (let i = 0; i < wdGroup.length; i++) {
        let wdArr = wdGroup[i];
        wdPoints[i] = [];

        for (let j = 0; j < wdArr.length; j++) {
            let xy = getXY(wdArr[j], curDate, 35, 42, wdYSection, 'tw');
            wdPoints[i].push(xy);
        }
    }

    let xlPath = ''
    let mbPath = ''
    let wdPath = ''

    // 心率
    for (let i = 0; i < xlPoints.length; i++) {
        let xlPoint = xlPoints[i];

        for (let j = 0; j < xlPoint.length; j++) {
            let x = xlPoint[j].x;
            let y = xlPoint[j].y;

            if (j === 0) {
                xlPath += "M" + x + "," + y;
            } else {
                xlPath += "L" + x + "," + y;
            }

            // 心率的圆点
            let _xlCyclePoint = xl_cycle({ x: x, y: y }, `心率：${xlPoint[j].value}`);
            pointArray.push(_xlCyclePoint);
        }
    }

    // 脉搏
    for (let i = 0; i < mbPoints.length; i++) {
        let mbPoint = mbPoints[i];

        for (let j = 0; j < mbPoint.length; j++) {
            let x = mbPoint[j].x;
            let y = mbPoint[j].y;

            if (j === 0) {
                mbPath += "M" + x + "," + y;
            } else {
                mbPath += "L" + x + "," + y;
            }

            // 脉搏的圆点
            let _mbCyclePoint = mb_cycle({ x: x, y: y }, `脉搏：${mbPoint[j].value}`);
            pointArray.push(_mbCyclePoint);
        }

    }

    // 体温
    for (let i = 0; i < wdPoints.length; i++) {
        let wdPoint = wdPoints[i];

        for (let j = 0; j < wdPoint.length; j++) {
            let x = wdPoint[j].x;
            let y = wdPoint[j].y;

            if (j === 0) {
                wdPath += "M" + x + "," + y;
            } else {
                wdPath += "L" + x + "," + y;
            }

            let types = wdPoint[j].type;
            let _wdCyclePoint;

            let wd_section = wdPoint[j].point.value; // 温度区间的值，当小于35度，为35度
            if (wd_section < 35) {
                // wd_section = '不升';
                pointArray.push(drawArrow({ x: x, y: 45 * height }, 3 * height, false, 'red'));
                // let valueArray = "不升".split("");

                //显示在35度下面
                // let cy = 42 * height;
                // for (let k = 0; k < valueArray.length; k++) {
                //     pointArray.push(<text key={x + 'bs' + k} x={x + 10} y={cy + height * k + 12}
                //         fill='#f00'>{valueArray[k]}</text>);
                // }

            }

            // 口温kw、腋温yw、肛温gw、耳温erw、额温ew, 默认腋温
            if (types === 'kw') {
                _wdCyclePoint = tw_mouth({ x: x, y: y }, `体温：${wd_section}`);
            } else if (types === 'gw') {
                _wdCyclePoint = tw_anal({ x: x, y: y }, `体温：${wd_section}`);
            }
            else if (types === 'erw') {
                _wdCyclePoint = tw_ear({ x: x, y: y }, `体温：${wd_section}`);
            }
            else if (types === 'ew') {
                _wdCyclePoint = tw_forehead({ x: x, y: y }, `体温：${wd_section}`);

            } else {
                _wdCyclePoint = tw_axillary({ x: x, y: y }, `体温：${wd_section}`);
            }

            // 体温的圆点
            pointArray.push(_wdCyclePoint);

            // 物理降温 升温
            let phValue = wdPoint[j].point.phValue; //物理温度

            if (phValue !== null && phValue !== undefined && phValue !== "") {
                let phv = wdPoint[j].value >= phValue ? "物理降温" : '升温';

                let wljwY = getXY(wdPoint[j].point, curDate, 35, 42, wdYSection, 'phValue');
                pointArray.push(xl_cycle({ x: wljwY.x, y: wljwY.y }, `${phv}：${wljwY.value}`))

                let phPath = ''
                phPath += "M" + x + "," + y;
                phPath += "L" + wljwY.x + "," + wljwY.y;

                keyIdx++;
                pointArray.push(<path key={"phPath" + keyIdx} strokeDasharray="3,3" stroke="red" strokeWidth='2' fill='none' d={phPath} />);

            }

        }

    }

    pointArray.push(<path key={"pathXL"} stroke="red" strokeWidth='2' fill='none' d={xlPath} />);
    pointArray.push(<path key={"pathMB"} stroke="red" strokeWidth='2' fill='none' d={mbPath} />);
    pointArray.push(<path key={"pathwd"} stroke="blue" strokeWidth='2' fill='none' d={wdPath} />);

    // pointArray.reverse(); /**把线反转到下面，以防折线遮住提示文字 @hulinha */

    return pointArray
}

/**
 * @method getXY 计算在svg中的x、y值
 * @param {JSON} point 录入信息
 * @param {String} beginDate 开始时间
 * @param {Number} originY 坐标原点显示刻度
 * @param {Number} maxY 最大刻度
 * @param {Array} ySection y值区间
 * @param {Boolean} type phValue / tw 返回phVlaue(物理降温)对应的xy,false value值 返回对应的xy,默认为true
 */
function getXY(point, beginDate, originY, maxY, ySection, type) {

    //hulinhua
    let curDate = point.date + " " + point.hour + ":00";

    let value = type === 'phValue' ? parseFloat(point.phValue) : parseFloat(point.value);
    if (type === 'tw') {
        value = value > 35 ? value : 35;

    }
    let height = 15;
    let daysW = height * 6;
    let Yheight = Math.abs(ySection[0] - ySection[1]);
    //一刻度是几个像素，y轴
    let Ypxs = Yheight / (maxY - originY); //原点为(0,0)
    let disTop = parseFloat(ySection[1]);

    let xPx = getDisDays(beginDate, curDate) * daysW;
    let yPx = Math.round((Yheight + disTop) - Ypxs * (value - originY));
    return {
        x: xPx,
        y: yPx,
        value: value,
        type: point.type,
        point: point,
    }

}




/**
 * @method splitGroup 根据请假事件分组
 * @param {Array} leaveEvent 请假事件
 * @param {Array} point 录入信息
 * @param {Bool} isTw 是否是体温 没有
 */
function splitGroup(leaveEvent, point, isTw) {
    //没有请假事件
    if (leaveEvent.length === 0) {
        return [point];
    }
    //按请假事件分组 根据请假事件的数量，判断分组数量
    let groupArray = [];
    let groupRule = []; //缓存分组规则

    let groupNum = leaveEvent.length + 1; //分组数量
    for (let i = 0; i < groupNum; i++) { // 计算分组规则
        groupRule[i] = {};
        if (i === 0) {
            groupRule[i].min = leaveEvent[i];
        } else if (i === groupNum - 1) {
            groupRule[i].max = leaveEvent[i - 1];
        } else {
            groupRule[i].min = leaveEvent[i - 1];
            groupRule[i].max = leaveEvent[i];
        }
    }

    let wd_low_mark = [];

    //将录入信息根据请假事件分组
    for (let i = 0; i < groupRule.length; i++) {
        let min = groupRule[i].min;
        let max = groupRule[i].max;
        groupArray[i] = []; //初始化
        for (let j = 0; j < point.length; j++) {
            let time = point[j].dataTime;
            if (judgeIn(time, min, max)) {
                groupArray[i].push(point[j]);


                if (isTw && point[j].value < 35) {

                    wd_low_mark.push({
                        mark_i: i,
                        mark_j: groupArray[i].length - 1
                    })

                }
            }
        }
    }

    if (isTw && wd_low_mark.length > 0) {

        let tw_low_Arr = [];
        for (let i = 0; i < wd_low_mark.length; i++) {
            let idx_i = wd_low_mark[i].mark_i;
            let idx_j = wd_low_mark[i].mark_j;
            let item = groupArray[idx_i][idx_j];
            tw_low_Arr.push(item);
        }

        for (let i = 0; i < wd_low_mark.length; i++) {

            let idx_i = wd_low_mark[i].mark_i;
            let idx_j = wd_low_mark[i].mark_j;
            let item_arr = groupArray[idx_i];
            item_arr.splice([idx_j], 1);

        }

        tw_low_Arr.forEach(element => {
            groupArray.push([element]);
        });
    }

    return groupArray;
}

/**
 * @method judgeIn 判断当前时间是否处于某个时间段
 * @param {String} curTime 当前时间
 * @param {String} minTime 最小时间
 * @param {String} maxTime 最大时间
 * @return {Boolean}
 */
function judgeIn(curTime, minTime, maxTime) {
    curTime = new Date(curTime.replace(/-/g, "/"));
    minTime = minTime ? new Date(minTime.replace(/-/g, "/")) : 0;
    maxTime = maxTime ? new Date(maxTime.replace(/-/g, "/")) : 0;
    if (!minTime && maxTime) { //最小时间未定义，则返回是否大于最大值
        if (curTime > maxTime) {
            return true;
        }
    }
    if (minTime && !maxTime) {
        if (curTime <= minTime) {
            return true;
        }
    }
    if (minTime && maxTime) {
        if (curTime > minTime && curTime <= maxTime) {
            return true;
        }
    }
}

/**
 * @method drawArrow 绘制箭头
 * @param {JSON} xy 坐标 {x:x,y:y}
 * @param {Number} length 箭头长度
 * @param {Boolean} type 箭头类型
 * @param {String} color 箭头颜色
 */
function drawArrow(xy, length, type, color, title) {
    let x = xy.x;
    let y1 = xy.y - length;
    let y2 = xy.y - 3;
    if (type) {
        x = xy.x;
        y1 = xy.y;
        y2 = xy.y - length + 3;
    }
    keyIdx++;
    return (
        <svg key={keyIdx + 'daryarrow'}>
            <line x1={x} y1={y1} x2={x} y2={y2} style={{ stroke: color, strokeWidth: 1.3 }}
                markerEnd='url(#markerArrow)' />
            <defs>
                <marker id='markerArrow' markerWidth='8' markerHeight='8' refX='4' refY='4.5' orient='auto'>
                    <path d='M1.62,1.62 L1.62,7.92 L7.2,4.32 L1.62,1.62' style={{ fill: color }}
                        title={title ? title : ""} />
                </marker>
            </defs>
        </svg>
    );
}


function drawEvent(evenArray, curDate) {


    if (evenArray === null || evenArray === undefined || evenArray.length === 0) {
        return [];
    }

    let chinese = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
    let daysW = 15 * 6;
    let height = 15;
    let timeArray = {};
    for (let i = 0; i < evenArray.length; i++) {
        //hulinhua
        let dataTime = evenArray[i].date + " " + evenArray[i].hour + ":00";

        // 初始化 dataTime 数组
        if (timeArray[dataTime] === undefined) {
            timeArray[dataTime] = [];
        }
        timeArray[dataTime].push(evenArray[i]);
    }


    let showArray = [];
    let xPxArray = [];
    for (const time in timeArray) {

        let evens = timeArray[time];
        let xPx = getDisDays(curDate, time) * daysW - 5.5;
        let show = "";
        let k = 0;

        for (let j = 0; j < evens.length; j++) {
            const curEven = evens[j];
            let value = curEven.value;

            // let dateTime = new Date(curEven.dataTime);
            let dateTime = datetimeStrToDate(curEven.dataTime);
            let hour = parseInt(dateTransform(dateTime, 'hh'));
            let minute = parseInt(dateTransform(dateTime, 'mm'));
            let hourStr = hour.toString();
            let minuteStr = minute.toString();
            let finalValue = "";

            let notShowTime = value === '请假' || value === '过敏' || value === '手术' || value === '拒测'; // 事件不展示时间

            if (minute > 0) {
                finalValue = value + (notShowTime ? "" : "||" + numToChinese(hourStr, chinese) + "时" + numToChinese(minuteStr, chinese) + "分");
            } else {
                finalValue = value + (notShowTime ? "" : "||" + numToChinese(hourStr, chinese) + "时整");
            }

            if (k === 0) {
                show += finalValue;
            } else {
                show += " " + finalValue;
            }
            k++;

        }
        showArray.push(show);
        xPxArray.push(xPx);
    }

    // console.log('timeArray', showArray, xPxArray)

    //绘制事件
    let reShowArray = [];
    for (let i = 0; i < showArray.length; i++) {
        //绘制path
        let xPx = xPxArray[i];
        let textArray = showArray[i].split("");
        reShowArray.push(
            <svg key={i}>
                {textArray.map((v, i) => {
                    return <text style={{ fontSize: v === '|' ? '13px' : '' }} key={i} x={v === '|' ? (xPx + 4) : xPx}
                        y={12 + 75 + i * height} fill="red">{v}</text>
                })}
            </svg>
        )
    }

    return reShowArray;

}

/**
 * @method numToChinese 将阿拉伯数字转换成中文数字
 * @param {Array} numArray 阿拉伯数字数组
 * @param {Array} chineseArray 中文数字数组
 * @return
 * */
function numToChinese(numArray, chineseArray) {
    let finalStr = "";
    if (numArray.length === 1) {
        finalStr = chineseArray[parseInt(numArray[0])];
        return finalStr;
    } else {
        if (numArray[0] === "1") {
            if (numArray[1] === "0") {
                finalStr += "十";
            } else {
                finalStr += "十" + chineseArray[parseInt(numArray[1])];
            }
        } else {
            if (numArray[1] === "0") {
                finalStr += chineseArray[parseInt(numArray[0])] + "十";
            } else {
                finalStr += chineseArray[parseInt(numArray[0])] + "十" + chineseArray[parseInt(numArray[1])];
            }
        }
    }
    return finalStr;
}

/**
 * @method getDisDays 计算时间段间隔多少小时
 * @param {String/Date} beginDate 开始时间
 * @param {String/Date} endDate 结束时间
 * @param {Number} beginHour 起始时刻
 * @return
 */
function getDisDays(beginDate, endDate, beginHour) {

    //判断是否是Date对象
    if (!(beginDate instanceof Date)) {
        beginDate = new Date(beginDate.replace(/-/g, "/"));
    }
    if (!(endDate instanceof Date)) {
        endDate = new Date(endDate.replace(/-/g, "/"));
    }
    return (endDate - beginDate) / (3600 * 1000 * 24);
}

/**
 * 
 * @param {日期时间字符串} time 格式如“2017-06-23 17:00:00”
 */
function datetimeStrToDate(time) {
    if (!time) {
        return null;
    } else {
        time = time.replace(/-/g, ':').replace(' ', ':');
        time = time.split(':');
        return new Date(time[0], (time[1] - 1), time[2], time[3], time[4], time[5]);
    }
}



export {
    tw_mouth,
    tw_anal,
    mb_cycle,
    xl_cycle,
    tw_axillary,
    tw_ear,
    tw_forehead,
    parseRePoint,
    drawEvent,
}